// 判断每个子在当前位置中可以移动的位置
import util from "@/src/util/Util.js"
export let rule = {

	// 车
	che: function(pieces, piece) {

		return che(pieces, piece);
	},
	ma: function(pieces, piece) {

		return ma(pieces, piece);
	},
	xiang: function(pieces, piece) {

		return xiang(pieces, piece);
	},
	shi: function(pieces, piece) {

		return shi(pieces, piece);
	},
	jiang: function(pieces, piece) {

		return jiang(pieces, piece);
	},
	pao: function(pieces, piece) {

		return pao(pieces, piece);
	},
	bing: function(pieces, piece) {

		return bing(pieces, piece);
	}

}

function che(pieces, piece) {
	// 获取距离最近的几个棋子
	/**
	 * {
		left: ,
		right: ,
		up: ,
		down:
	}
	 */
	let ajion = util.getAjoin(pieces, piece);
	let points = [];

	// 到左边有多少个位置
	let leftCount = piece.coo[0] - (ajion.left != undefined ? ajion.left.coo[0] : 0);
	if (ajion.left != undefined && util.isSamePieceCamp(piece.code, ajion.left.code)) {
		// 如果是同阵营则棋子要少移动一位
		leftCount -= 1;
	}

	let rightCount = (ajion.right != undefined ? ajion.right.coo[0] : 8) - piece.coo[0];
	if (ajion.right != undefined && util.isSamePieceCamp(piece.code, ajion.right.code)) {
		// 如果是同阵营则棋子要少移动一位
		rightCount -= 1;
	}

	// 到下边边有多少个位置
	let downCount = piece.coo[1] - (ajion.down != undefined ? ajion.down.coo[1] : 0);
	if (ajion.down != undefined && util.isSamePieceCamp(piece.code, ajion.down.code)) {
		// 如果是同阵营则棋子要少移动一位
		downCount -= 1;
	}

	let upCount = (ajion.up != undefined ? ajion.up.coo[1] : 9) - piece.coo[1];
	if (ajion.up != undefined && util.isSamePieceCamp(piece.code, ajion.up.code)) {
		// 如果是同阵营则棋子要少移动一位
		upCount -= 1;
	}

	for (let i = 1; i <= leftCount; i++) {
		points.push([piece.coo[0] - i, piece.coo[1]])
	}
	for (let i = 1; i <= rightCount; i++) {
		points.push([piece.coo[0] + i, piece.coo[1]])
	}
	for (let i = 1; i <= downCount; i++) {
		points.push([piece.coo[0], piece.coo[1] - i])
	}
	for (let i = 1; i <= upCount; i++) {
		points.push([piece.coo[0], piece.coo[1] + i])
	}

	return points;
}

function ma(pieces, piece) {
	// 马走日，需要判别是否蹩马腿问题。
	// 先拿到马所能走的所有路径，
	// 横坐标加+-2 后纵坐标 +-1
	// 纵坐标+- 2 后横坐标 +-1,
	// 也就是正常情况下能走的位置有4+4= 8
	// 先一个个列出
	let points = [];
	let pieceX = piece.coo[0];
	let pieceY = piece.coo[1];
	points.push([pieceX + 2, pieceY + 1]);
	points.push([pieceX + 2, pieceY - 1]);
	points.push([pieceX - 2, pieceY + 1]);
	points.push([pieceX - 2, pieceY - 1]);
	points.push([pieceX + 1, pieceY + 2]);
	points.push([pieceX - 1, pieceY + 2]);
	points.push([pieceX + 1, pieceY - 2]);
	points.push([pieceX - 1, pieceY - 2]);
	// 解决蹩马腿问题
	// 找四个方向上是否有棋子
	let ajoin = util.getAjoin(pieces, piece);

	if (ajoin.up != undefined && ajoin.up.coo[1] == pieceY + 1) {
		// 去排除上面的几个路线
		points = points.filter(p => p[1] != pieceY + 2);
	}
	if (ajoin.down != undefined && ajoin.down.coo[1] == pieceY - 1) {
		points = points.filter(p => p[1] != pieceY - 2);
	}
	if (ajoin.left != undefined && ajoin.left.coo[0] == pieceX - 1) {
		points = points.filter(p => p[0] != pieceX - 2);
	}
	if (ajoin.right != undefined && ajoin.right.coo[0] == pieceX + 1) {
		points = points.filter(p => p[0] != pieceX + 2);
	}

	// 处理小于0，横坐标大于8，纵坐标大于9的问题
	points = points.filter(p => p[0] >= 0 && p[0] <= 8 && p[1] >= 0 && p[1] <= 9);

	// 最后排除如果这几个点位上有自己的棋子则无法落子
	points = points.filter(p => {
		let pPiece = util.getPieceByCoo(pieces, p);
		if (pPiece != undefined) {
			return !util.isSamePieceCamp(pPiece.code, piece.code);
		}
		return true;
	});

	return points;
}

function xiang(pieces, piece) {

	// 相走田，考虑别象腿的问题，像可以走的点可以列举出来，红黑方各自不同
	// 红方：0-2. 2-0. 2-4，4-2，6-0，6-4，8-2
	// 黑方：0-7. 2-5. 2-9，4-7，6-9，6-5，8-7
	let points = [];
	if (util.getPieceCamp(piece.code) == "r") {
		points = [
			[0, 2],
			[2, 0],
			[2, 4],
			[4, 2],
			[6, 0],
			[6, 4],
			[8, 2]
		];
	} else {
		points = [
			[0, 7],
			[2, 5],
			[2, 9],
			[4, 7],
			[6, 9],
			[6, 5],
			[8, 7]
		];
	}
	// 根据当前相的位置，然后排除掉不可到达的位置
	let cur = piece.coo;
	points = points.filter(p => {
		let r1 = false;
		if (cur[0] - 2 >= 0) {
			r1 = p[0] == cur[0] - 2;
		}
		let r2 = false;
		if (cur[0] + 2 <= 8) {
			r2 = p[0] == cur[0] + 2;
		}
		return r1 || r2;
	});

	// 处理别象腿的问题，相每次最多有4个位置可以走,把所有点列出来，如果这个点x轴小于当前棋子，则
	// 判断当前点位的x-1为别腿点的x，反之相加，y轴计算类似
	// TODO 解决黑色方的问题。。。
	points = points.filter(p => {
		let bie = [];
		if (p[0] < cur[0]) {
			bie[0] = cur[0] - 1;
		} else {
			bie[0] = cur[0] + 1;
		}

		if (p[1] < cur[1]) {
			bie[1] = cur[1] - 1;
		} else {
			bie[1] = cur[1] + 1;
		}

		return util.getPieceByCoo(pieces, bie) == undefined;
	});

	// 排除这个位置被自己棋子占用的所有点位
	points = points.filter(p => {
		let pPiece = util.getPieceByCoo(pieces, p);
		if (pPiece != undefined) {
			return !util.isSamePieceCamp(pPiece.code, piece.code);
		}
		return true;
	});

	return points;

}

function shi(pieces, piece) {
	// 士比较简单，直接判断交叉的位置，但是有一定的范围
	// 先判断是红方还是黑方
	// 根据不同阵营进行处理
	let points = [];
	if (util.getPieceCamp(piece.code) == "r") {
		if (piece.coo[1] == 1) {
			points = [
				[3, 0],
				[5, 0],
				[3, 2],
				[5, 2]
			];
		} else {
			points = [[4, 1]];
		}
	} else {
		if (piece.coo[1] == 8) {
			points = [
				[3, 9],
				[5, 9],
				[3, 7],
				[5, 7]
			];
		} else {
			points = [[4, 8]];
		}
	}

	// 排除这个位置被自己棋子占用的所有点位
	points = points.filter(p => {
		let pPiece = util.getPieceByCoo(pieces, p);
		if (pPiece != undefined) {
			return !util.isSamePieceCamp(pPiece.code, piece.code);
		}
		return true;
	});

	return points;
}

function jiang(pieces, piece) {

	// 与士兵类似
	let points = [
		[piece.coo[0] + 1, piece.coo[1]],
		[piece.coo[0], piece.coo[1] + 1],
		[piece.coo[0] - 1, piece.coo[1]],
		[piece.coo[0], piece.coo[1] - 1]
	];

	points = points.filter(p => {
		if (util.getPieceCamp(piece.code) == "r") {
			return p[0] >= 3 && p[0] <= 5 && p[1] <= 2 && p[1] >= 0;
		} else {
			return p[0] >= 3 && p[0] <= 5 && p[1] <= 9 && p[1] >= 7;
		}
	});

	// 排除这个位置被自己棋子占用的所有点位
	points = points.filter(p => {
		let pPiece = util.getPieceByCoo(pieces, p);
		if (pPiece != undefined) {
			return !util.isSamePieceCamp(pPiece.code, piece.code);
		}
		return true;
	});

	return points;
}

function pao(pieces, piece) {

	// 炮的路径和车相似，但是不能再直线上吃子，只能翻山吃子
	// 想个算法，分为两步骤来做，第一步做能走的位置
	// 可移动的位置
	let ajion = util.getAjoin(pieces, piece);
	let points = [];
	let leftCount = piece.coo[0] - (ajion.left != undefined ? ajion.left.coo[0] : -1);
	let rightCount = (ajion.right != undefined ? ajion.right.coo[0] : 9) - piece.coo[0];
	let downCount = piece.coo[1] - (ajion.down != undefined ? ajion.down.coo[1] : -1);
	let upCount = (ajion.up != undefined ? ajion.up.coo[1] : 10) - piece.coo[1];

	for (let i = 1; i < leftCount; i++) {
		points.push([piece.coo[0] - i, piece.coo[1]])
	}
	for (let i = 1; i < rightCount; i++) {
		points.push([piece.coo[0] + i, piece.coo[1]])
	}
	for (let i = 1; i < downCount; i++) {
		points.push([piece.coo[0], piece.coo[1] - i])
	}
	for (let i = 1; i < upCount; i++) {
		points.push([piece.coo[0], piece.coo[1] + i])
	}
	let x_pieces = util.getXPiece(pieces, piece.coo[1]);
	let y_pieces = util.getYPiece(pieces, piece.coo[0]);
	// 必须一条轴上的子有3个才能产生吃子,中间被任何棋子隔开的另一个棋子是对方的棋子
	let currXIndex;
	x_pieces.forEach((item, index) => {
		if (item.code == piece.code) {
			currXIndex = index;
			return;
		}
	});

	let currYIndex;
	y_pieces.forEach((item, index) => {
		if (item.code == piece.code) {
			currYIndex = index;
			return;
		}
	});

	let intervalPieces = [y_pieces[currYIndex + 2], y_pieces[currYIndex - 2], x_pieces[currXIndex + 2], x_pieces[
		currXIndex - 2]];
	intervalPieces.forEach((intervalPiece) => {
		if (intervalPiece != undefined && !util.isSamePieceCampByCoo(pieces, intervalPiece.coo, piece.coo)) {
			points.push(intervalPiece.coo);
		}
	})
	
	return points;
}

function bing(pieces, piece) {

	let points = [];
	let type = util.getPieceCamp(piece.code);
	if (type == "r") {
		if(piece.coo[1] <= 4){
			points = [[piece.coo[0], piece.coo[1] + 1]];
		}else{
			points = [[piece.coo[0], piece.coo[1] + 1],[piece.coo[0] + 1, piece.coo[1]],[piece.coo[0] - 1, piece.coo[1]]];
		}
		
	}else{
		if(piece.coo[1] >= 6){
			points = [[piece.coo[0], piece.coo[1] - 1]];
		}else{
			points = [[piece.coo[0], piece.coo[1] + 1],[piece.coo[0] + 1, piece.coo[1]],[piece.coo[0] - 1, piece.coo[1]]];
		}
	}
	
	points = points.filter(p => p[0] >= 0 && p[0] <= 8 && p[1] >= 0 && p[1] <= 9);
	// 排除这个位置被自己棋子占用的所有点位
	points = points.filter(p => {
		let pPiece = util.getPieceByCoo(pieces, p);
		if (pPiece != undefined) {
			return !util.isSamePieceCamp(pPiece.code, piece.code);
		}
		return true;
	});
	
	return points;
}
